From 4cc3e63e98b1adaaf6aedc09830569767d5eb653 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Thu, 21 Mar 2024 14:43:39 -0500 Subject: [PATCH] Use importlib.metadata instead of pkg_resources for entrypoint processing --- setup.py | 2 ++ src/pgwui_common/plugin.py | 20 ++++++++++++---- tests/test_plugin.py | 47 +++++++++++++++++++++----------------- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/setup.py b/setup.py index cdd4ad6..98dc527 100644 --- a/setup.py +++ b/setup.py @@ -143,6 +143,8 @@ setup( # Run-time dependencies. install_requires=[ 'pgwui_core==' + version, + # for plugin.py's entrypoint processing. + 'importlib_metadata > 3.6 ; python_version < "3.10"', 'pyramid', 'pyramid_beaker', 'pyramid_mako', diff --git a/src/pgwui_common/plugin.py b/src/pgwui_common/plugin.py index ab7215f..f69bafc 100644 --- a/src/pgwui_common/plugin.py +++ b/src/pgwui_common/plugin.py @@ -22,7 +22,16 @@ '''Plugin support library for PGWUI ''' -import pkg_resources +import sys + +if sys.version_info < (3, 10): + import importlib_metadata + + class importlib: + pass + setattr(importlib, 'metadata', importlib_metadata) +else: + import importlib.metadata def get_component(module): @@ -34,8 +43,8 @@ def get_component(module): def find_pgwui_components(): '''Return list of all pgwui component names as strings ''' - return [get_component(entry_point.resolve().__name__) for entry_point in - pkg_resources.iter_entry_points('pgwui.components')] + return [get_component(entry_point.module) for entry_point in + importlib.metadata.entry_points(group='pgwui.components')] def find_pgwui_check_settings(): @@ -43,7 +52,8 @@ def find_pgwui_check_settings(): component ''' check_settings = dict() - for entry_point in pkg_resources.iter_entry_points('pgwui.check_settings'): - callable = entry_point.resolve() + for entry_point in importlib.metadata.entry_points( + group='pgwui.check_settings'): + callable = entry_point.load() check_settings[get_component(callable.__module__)] = callable return check_settings diff --git a/tests/test_plugin.py b/tests/test_plugin.py index bd1fa8e..439bb5a 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -26,23 +26,16 @@ from pgwui_common import plugin # Helper classes +# (We might want to mock this, but what module defines EntryPoint()?) class MockEntryPoint(): def __init__(self, val): + self.module = val self.__module__ = val - self.__name__ = val - def resolve(self): + def load(self): return self -class MockPkgResources(): - def __init__(self, entry_points): - self.entry_points = entry_points - - def iter_entry_points(self, *args): - return [MockEntryPoint(name) for name in self.entry_points] - - # get_component() @pytest.mark.unittest @@ -59,33 +52,45 @@ mock_get_component = testing.make_mock_fixture( # find_pgwui_components() +# Use late binding; eaiser since the module hierarchy is sometimes constructed +# because importlib.metadata sometimes uses a compatibility module. +mock_importlib_metadata_entry_points = testing.late_instance_mock_fixture( + 'entry_points') + + @pytest.mark.unittest -def test_find_pgwui_components(mock_get_component, monkeypatch): - '''Returns list of entry points via iter_entry_points() +def test_find_pgwui_components( + mock_get_component, mock_importlib_metadata_entry_points): + '''Returns collection of entry points via entry_points() ''' - entry_points = ['a', 'b', 'c'] + entry_point_modules = ['a', 'b', 'c'] + entry_points = [MockEntryPoint(mod) for mod in entry_point_modules] mock_get_component.side_effect = lambda x: x - monkeypatch.setattr( - plugin, 'pkg_resources', MockPkgResources(entry_points)) + mocked_importlib_metadata_entry_points = ( + mock_importlib_metadata_entry_points(plugin.importlib.metadata)) + mocked_importlib_metadata_entry_points.return_value = entry_points result = plugin.find_pgwui_components() - assert result == entry_points + assert result == entry_point_modules # find_pgwui_check_settings @pytest.mark.unittest -def test_find_pgwui_check_settings(mock_get_component, monkeypatch): +def test_find_pgwui_check_settings( + mock_get_component, mock_importlib_metadata_entry_points): '''Returns a dict, keyed by name, of entry points ''' - entry_points = ['a', 'b', 'c'] + entry_point_modules = ['a', 'b', 'c'] + entry_points = [MockEntryPoint(mod) for mod in entry_point_modules] mock_get_component.side_effect = lambda x: x - monkeypatch.setattr( - plugin, 'pkg_resources', MockPkgResources(entry_points)) + mocked_importlib_metadata_entry_points = ( + mock_importlib_metadata_entry_points(plugin.importlib.metadata)) + mocked_importlib_metadata_entry_points.return_value = entry_points result = plugin.find_pgwui_check_settings() assert isinstance(result, dict) - assert list(result.keys()).sort() == entry_points.sort() + assert list(result.keys()).sort() == entry_point_modules.sort() -- 2.34.1